package com.exsun.gateway.jt809.codec;

import com.exsun.gateway.jt809.common.FlowIdMgr;
import com.exsun.gateway.jt809.data.PushData;
import com.exsun.gateway.jt809.common.LinkMgr;
import com.exsun.gateway.jt809.config.NettyClientConfig;
import com.exsun.gateway.jt809.master.handler.JT809ClientInitializer;
import com.exsun.gateway.jt809.slave.handler.JT809ServerChannelInitializer;
import exsun.jt808.data.util.SAContextHolder;
import exsun.jt808.data.util.parse.BitOperator;
import exsun.jt808.data.util.parse.CRC16;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import io.netty.channel.Channel;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
public class MsgEncoder extends MessageToByteEncoder<List<PushData>> {
	private static final Logger logger = LoggerFactory.getLogger(MsgDecoder.class);

	NettyClientConfig nettyClientConfig;

	public MsgEncoder(){
	}

	public MsgEncoder(JT809ServerChannelInitializer jt809ServerChannelInitializer){
		this.nettyClientConfig = jt809ServerChannelInitializer.nettyClientConfig;
	}

	public MsgEncoder(JT809ClientInitializer jt809ClientInitializer) {
		this.nettyClientConfig = jt809ClientInitializer.nettyClientConfig;
	}


	@Override
	protected void encode(ChannelHandlerContext ctx, List<PushData> msgs, ByteBuf out) throws Exception {
		for (PushData msg: msgs) {
			int msgId = msg.getMsgId();
			byte[] msgBodyBytes = msg.getMsgBodyBytes();
			byte[] data = encode(msgId, msgBodyBytes, ctx.channel());
			logger.info("上报数据[{}]:{}",BitOperator.intToHex(msgId,4), ByteBufUtil.hexDump(data));
			out.writeBytes(data);
		}
	}

	private byte[] encode(int msgId, byte[] msgBodyBytes, Channel channel) throws Exception {
		int flowId = FlowIdMgr.getFlowId(channel.id());
		int len = msgBodyBytes == null ? 0 : msgBodyBytes.length;
		// 获取配置的centerId
		int centerId = nettyClientConfig.getSuperiorCenterId();
		// 消息头
		byte[] msgHeader = JT809ProtocolUtils.generateMsgHeader(msgId, len, centerId, flowId);
		// 连接消息头和消息体
		byte[] headerAndBody = BitOperator.concatAll(msgHeader, msgBodyBytes);
		// 校验码
		int crc = CRC16.getCRC(headerAndBody);
		// 连接并且转义
		return doEncode(headerAndBody, crc);
	}

	private byte[] doEncode(byte[] headerAndBody, int crc) throws Exception {
		byte[] crc_code = BitOperator.integerTo2Bytes(crc);
		byte[] noEscapedBytes = BitOperator.concatAll(headerAndBody, crc_code);
		byte[] message = BitOperator.concatAll(Arrays.asList(//
				new byte[] { 0x5b },
				JT809ProtocolUtils.doEscape4Send(noEscapedBytes), // 消息头消息体校验码
				new byte[] { 0x5d }
				));
		return message;
	}

}
